#include "calc.h"
#include <algorithm>


bool strLenSort(const string &a,const string &b){
	try {
		return a.size() > b.size();
	} catch (...) {
		throw;
	}
}


void calc::setRepMap(){
	try {
		maprep["+"] = "+";
		maprep["-"] = "-";
		maprep["*"] = "*";
		maprep["/"] = "/";
		maprep["%"] = "%";
		maprep["!"] = "!";
		maprep["^"] = "^";
		maprep["e"] = "e";
		maprep["abs"] = "A";
		maprep["ceil"] = "B";
		maprep["floor"] = "C";
		maprep["sqrt"] = "D";
		maprep["pow"] = "E";
		maprep["cos"] = "F";
		maprep["sin"] = "G";
		maprep["tan"] = "H";
		maprep["acos"] = "I";
		maprep["asin"] = "J";
		maprep["atan"] = "K";
		maprep["atan2"] = "L";
		maprep["sinh"] = "M";
		maprep["cosh"] = "N";
		maprep["tanh"] = "O";
		maprep["exp"] = "P";
		maprep["log"] = "Q";
		maprep["log10"] = "R";
		maprep["modf"] = "S";
		maprep["fmod"] = "T";
		maprep["ldexp"] = "U";
		maprep["ans"] = "0";
		maprep["avg"] = "V";
		maprep["sum"] = "W";
		maprep["dev"] = "X";
		maprep["devp"] = "Y";
		maprep["stddev"] = "Z";
		maprep["stddevp"] = "`";
		maprep["mid"] = "~";
		maprep["min"] = "@";
		maprep["max"] = "$";
		maprep["rand"] = "&";
		
		//define more function

		argNum["A"] = 1;
		argNum["B"] = 1;
		argNum["C"] = 1;
		argNum["D"] = 1;
		argNum["E"] = 2;
		argNum["F"] = 1;
		argNum["G"] = 1;
		argNum["H"] = 1;
		argNum["I"] = 1;
		argNum["J"] = 1;
		argNum["K"] = 1;
		argNum["L"] = 2;
		argNum["M"] = 1;
		argNum["N"] = 1;
		argNum["O"] = 1;
		argNum["P"] = 1;
		argNum["Q"] = 1;
		argNum["R"] = 1;
		argNum["S"] = 1;
		argNum["T"] = 2;
		argNum["U"] = 2;
		
		argNum["V"] = -1;
		argNum["W"] = -1;
		argNum["X"] = -1;
		argNum["Y"] = -2;
		argNum["Z"] = -1;
		argNum["`"] = -2;
		argNum["~"] = -1;
		argNum["@"] = -1;
		argNum["$"] = -1;
		argNum["&"] = 2;
		//add functions' short

		refreshMap();

		opIndex['+'] = 0;
		opIndex['-'] = 1;
		opIndex['*'] = 2;
		opIndex['/'] = 3;
		opIndex['%'] = 4;
		opIndex['!'] = 5;
		opIndex['^'] = 6;
		opIndex['e'] = 7;
		opIndex['('] = 8;
		opIndex[')'] = 9;
		opIndex['#'] = 10;


		op.clear();
		//  +-*/ %!^e()#
		op.push_back("11000000011");//+
		op.push_back("11000000011");//-
		op.push_back("11111000011");//*
		op.push_back("11111000011");///
		op.push_back("11111000011");//%
		op.push_back("11111011011");//!
		op.push_back("11111011011");//^
		op.push_back("11111111011");//e
		op.push_back("00000000010");//(
		op.push_back("11111111111");//)
		op.push_back("00000000001");//#


		errgrp[make_pair('+', '+')] = true;
		errgrp[make_pair('+', '-')] = true;
		errgrp[make_pair('+', 'd')] = true;
		errgrp[make_pair('+', '.')] = true;
		errgrp[make_pair('+', ',')] = true;
		errgrp[make_pair('+', ')')] = true;
		errgrp[make_pair('+', '#')] = true;

		errgrp[make_pair('-', '+')] = true;
		errgrp[make_pair('-', '-')] = true;
		errgrp[make_pair('-', 'd')] = true;
		errgrp[make_pair('-', '.')] = true;
		errgrp[make_pair('-', ',')] = true;
		errgrp[make_pair('-', ')')] = true;
		errgrp[make_pair('-', '#')] = true;

		errgrp[make_pair('d', '+')] = true;
		errgrp[make_pair('d', '-')] = true;
		errgrp[make_pair('d', 'd')] = true;
		errgrp[make_pair('d', '.')] = true;
		errgrp[make_pair('d', ',')] = true;
		errgrp[make_pair('d', ')')] = true;
		errgrp[make_pair('d', '#')] = true;

		errgrp[make_pair('s', '+')] = true;
		errgrp[make_pair('s', '-')] = true;
		errgrp[make_pair('s', 'd')] = true;
		errgrp[make_pair('s', 's')] = true;
		errgrp[make_pair('s', '.')] = true;
		errgrp[make_pair('s', ',')] = true;
		errgrp[make_pair('s', ')')] = true;
		errgrp[make_pair('s', '#')] = true;
		errgrp[make_pair('s', 'n')] = true;

		errgrp[make_pair('.', '+')] = true;
		errgrp[make_pair('.', '-')] = true;
		errgrp[make_pair('.', 'd')] = true;
		errgrp[make_pair('.', 's')] = true;
		errgrp[make_pair('.', '.')] = true;
		errgrp[make_pair('.', ',')] = true;
		errgrp[make_pair('.', '(')] = true;
		errgrp[make_pair('.', ')')] = true;
		errgrp[make_pair('.', '#')] = true;

		errgrp[make_pair(',', '+')] = true;
		errgrp[make_pair(',', '-')] = true;
		errgrp[make_pair(',', 'd')] = true;
		errgrp[make_pair(',', '.')] = true;
		errgrp[make_pair(',', ',')] = true;
		errgrp[make_pair(',', ')')] = true;
		errgrp[make_pair(',', '#')] = true;

		errgrp[make_pair('(', 'd')] = true;
		errgrp[make_pair('(', '.')] = true;
		errgrp[make_pair('(', ',')] = true;
		errgrp[make_pair('(', '#')] = true;

		errgrp[make_pair(')', 's')] = true;
		errgrp[make_pair(')', '.')] = true;
		errgrp[make_pair(')', '(')] = true;
		errgrp[make_pair(')', 'n')] = true;

		errgrp[make_pair('#', 'd')] = true;
		errgrp[make_pair('#', '.')] = true;
		errgrp[make_pair('#', ',')] = true;
		errgrp[make_pair('#', ')')] = true;
		errgrp[make_pair('#', '#')] = true;

		errgrp[make_pair('n', 's')] = true;
		errgrp[make_pair('n', '(')] = true;
	} catch (...) {
		throw;
	}
}


void calc::refreshMap() {
	try {
		shortSym.clear();
		for (map<string, int>::iterator p = argNum.begin(); p != argNum.end(); ++p) {
			shortSym.push_back(p->first);
		}

		repsort.clear();
		for (map<string, string>::iterator p = maprep.begin(); p != maprep.end(); ++p) {
			repsort.push_back(p->first);
		}
		sort(repsort.begin(), repsort.end(), strLenSort);
		outLog("refresh map");
	} catch (...) {
		throw;
	}
}